home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’95 / Reminder Manager / Play.c < prev    next >
Text File  |  1995-06-24  |  5KB  |  219 lines

  1. #define ON        1
  2. #define OFF        0
  3. #define NIL        0L
  4.  
  5. #include "Play.h"
  6. #include "DebugDisplay.h"
  7. #include "Lose.h"
  8. #include "Chimer.h"
  9. #include "limits.h"
  10.  
  11. // These are all kept in main.c
  12. extern char             PlayingFlag;        // Noise in progress flag
  13. extern short            BallFrequency;        // How often new balls are dropped
  14. extern long                ResolutionCounter;    // Keep track of the times
  15. extern long                Resolution;            // How many times to skip before going on
  16. extern short            wherewasI;            // Loop Counter for Play1
  17.  
  18. extern unsigned long    fudgefactor;
  19. extern unsigned long    fudgefactor2;
  20.  
  21. extern long                starvation;            // how often we get execution cycles
  22. extern unsigned long    starvTickCount;        // the last time we got an execution chance
  23. extern long                starvIncrement;        // the bonus multiplier fudge factor
  24. extern long                starvDecrement;        // how many ticks to take off the stack when noise
  25. extern long                deltastarv;
  26.  
  27. extern long                nextShower;            // the minutes of the next time
  28. extern long                showerInterval;        // minutes between showers
  29. extern long                showerDuration;        // seconds (roughly)
  30.  
  31. extern long                dissatisfaction;    // how often we get to play notes
  32. extern long                dissDecrement;        // how many ticks to take off the stack when noise
  33.  
  34. unsigned long            curTickCount;        // what time is it now?
  35.  
  36. #define BALLS  6
  37. char Ball_List[BALLS];
  38.  
  39. #define STATES        7
  40. #define EMPTY         0
  41. #define DROP         1
  42. #define CHIME1         2
  43. #define CHIME2         3
  44. #define CHIME3         4
  45. #define CHIME4         5
  46. #define CLINK         6
  47.  
  48. // StateList[1][3] means that the starting state is 1, 
  49. // the ending state is 3, and the probability of going from
  50. // state 1 to state 3 is 0.20 (out of 1.00)
  51. const float StateList[STATES][STATES] = {
  52.     1.00,0.00,0.00,0.00,0.00,0.00,0.00,  // Start = EMPTY  = 0
  53.     0.00,0.00,0.20,0.20,0.20,0.20,0.10,     // Start = DROP   = 1
  54.     0.40,0.00,0.05,0.25,0.05,0.15,0.10,  // Start = Chime1 = 2
  55.     0.70,0.00,0.14,0.05,0.01,0.05,0.05,  // Start = Chime2 = 3
  56.     0.40,0.00,0.05,0.15,0.05,0.25,0.10,  // Start = Chime3 = 4
  57.     0.70,0.00,0.01,0.05,0.14,0.05,0.05,  // Start = Chime4 = 5
  58.     1.00,0.00,0.00,0.00,0.00,0.00,0.00};  // Start = CLINK = 6
  59. //   MT    DR   1    2    3    4    CLINK
  60.  
  61. void Init_Play(void)
  62. {
  63.     int i;
  64.     unsigned long foo;
  65.     
  66.     PlayingFlag = TRUE;
  67.     
  68.     // init the ball list
  69.     for (i=0;i<BALLS;i++)
  70.         Ball_List[i]=EMPTY;
  71.     
  72.     // Gimme random numbers
  73.     GetDateTime(&foo);
  74.     qd.randSeed = foo;
  75.  
  76.     // Initialize the Counters
  77.     curTickCount = TickCount();
  78.     deltastarv = 0;
  79.     starvation = 0;
  80.     starvTickCount = curTickCount;
  81.     dissatisfaction = 0;
  82.  
  83.     // Open the display window
  84.     OpenDisplay();
  85. }
  86.  
  87. void Cease_Play(void)
  88. {
  89.     PlayingFlag = FALSE;
  90.     DisposeDisplay();
  91. }
  92.  
  93. // If a serious error happens (file system, etc)
  94. void Explode(void)
  95. {
  96.     Cease_Play();
  97.     A_Lose();
  98. }
  99.  
  100. void Shower(void)
  101. {
  102.     DateTimeRec d;
  103.     
  104.     GetTime(&d);
  105.  
  106.     // when the time comes, nail the storm value
  107.     if (d.minute==nextShower)
  108.         dissatisfaction = 255;
  109.  
  110.     // after the duration of the storm, update the
  111.     // time of the next shower (which coincidentally
  112.     // causes the above clause to stop executing...)
  113.     if (d.second>showerDuration)
  114.         nextShower = (((1+(d.minute/showerInterval))*showerInterval) % 60);
  115. }
  116.  
  117. void Play1(void)
  118. {
  119.     short oldstate,newstate;
  120.     long tempstarv,tempsatis,i;
  121.  
  122.     // Set up all the current counting stuff
  123.     curTickCount = TickCount();
  124.  
  125.     tempstarv = (curTickCount-starvTickCount)/starvIncrement;
  126.     deltastarv = tempstarv-starvation;
  127.     starvation = (7*starvation+tempstarv)/8;
  128.     if (starvation>255) starvation = 255;        
  129.     
  130.     starvation -= starvDecrement;
  131.     if (starvation<0) starvation = 0;
  132.  
  133.     if (starvation>fudgefactor2) dissatisfaction += (deltastarv/starvIncrement);
  134.     if (dissatisfaction>255) dissatisfaction = 255;
  135.  
  136.     dissatisfaction -= dissDecrement;
  137.     if (dissatisfaction<0) dissatisfaction = 0;
  138.     
  139.     Shower();
  140.  
  141.     UpdateDisplay();
  142.  
  143.     // use the storm variable to increase the likelihood
  144.     // that a noise will be made -- this makes the noise
  145.     // "trickle off."
  146.     for (i=0;i<(dissatisfaction*dissatisfaction);i+=50)
  147.         if ((deltastarv<20) && timetodrop()) 
  148.         {
  149.             DropBall();
  150.             break;
  151.         };
  152.  
  153.     for (i=0;i<BALLS;i++)
  154.     {
  155.         oldstate = Ball_List[wherewasI];
  156.         newstate = ChangeStates(oldstate);
  157.         Ball_List[wherewasI] = newstate;
  158.         
  159.         if ((newstate!=oldstate) && (newstate>1))
  160.         {
  161.             PlayAChime(newstate);
  162.         }
  163.     }
  164.     // Put the current tickcount into the old tickcount
  165.     starvTickCount = curTickCount;
  166. }
  167.  
  168. Boolean timetodrop(void)
  169. {
  170.     unsigned long ronda;
  171.  
  172.     // if you're totally starved for time, don't go making noise.
  173.     if (starvation<fudgefactor)
  174.     {
  175.         ronda = (Random() & 0x7FFF);
  176.         return (ronda > (128*(BallFrequency)));
  177.     }
  178.     else
  179.         return FALSE;    
  180. }
  181.  
  182. void DropBall(void)
  183. {
  184.     int i;
  185.         
  186.     for (i=0;i<BALLS;i++)
  187.         if (Ball_List[i]==EMPTY) 
  188.         {
  189.             Ball_List[i] = DROP;
  190.             break;
  191.         }
  192. }
  193.  
  194. short ChangeStates(short startstate)
  195. {
  196.     float    foo;
  197.     float    bar;
  198.     short    i;
  199.         
  200.     // hot-wire the obvious cases
  201.     if (startstate == EMPTY)
  202.         return EMPTY;
  203.     if (startstate == CLINK)
  204.         return EMPTY;
  205.     
  206.     // Make foo be a random number from 0 to 1
  207.     foo = (float)(Random() & 0x7FFF) / (float)SHRT_MAX;
  208.     bar = 0.00;
  209.     
  210.     for (i=0;i<STATES;i++)
  211.     {
  212.         bar += StateList[startstate][i];
  213.         if (bar > foo)
  214.             return i;
  215.     };
  216.     
  217.     return EMPTY;
  218. }
  219.